#include "stdafx.h"
#include "log/logregistry.hpp"
#include "designpattern/singletonholder.hpp"
using JHCPP::designpattern::TSingletonHolder;


namespace JHCPP
{
	namespace log
	{
		CLogRegistry::CLogRegistry()
		{
		}

		CLogRegistry::~CLogRegistry()
		{
		}


		CChannel* CLogRegistry::channelForName(const std::string& name) const
		{
			CMutex::ScopedLock lock(m_mutex);

			ChannelMap::const_iterator it = m_channelMap.find(name);
			if (it != m_channelMap.end())
				return const_cast<CChannel*>(it->second.get());
			else
				throw NotFoundException("logging channel", name);
		}

		CFormatter* CLogRegistry::formatterForName(const std::string& name) const
		{
			CMutex::ScopedLock lock(m_mutex);

			FormatterMap::const_iterator it = m_formatterMap.find(name);
			if (it != m_formatterMap.end())
				return const_cast<CFormatter*>(it->second.get());
			else
				throw NotFoundException("logging formatter", name);
		}

		void CLogRegistry::registerChannel(const std::string& name, CChannel* pChannel)
		{
			CMutex::ScopedLock lock(m_mutex);

			m_channelMap[name] = ChannelPtr(pChannel, true);
		}

		void CLogRegistry::registerFormatter(const std::string& name, CFormatter* pFormatter)
		{
			CMutex::ScopedLock lock(m_mutex);

			m_formatterMap[name] = FormatterPtr(pFormatter, true);
		}

		void CLogRegistry::unregisterChannel(const std::string& name)
		{
			CMutex::ScopedLock lock(m_mutex);

			ChannelMap::iterator it = m_channelMap.find(name);
			if (it != m_channelMap.end())
				m_channelMap.erase(it);
			else
				throw NotFoundException("logging channel", name);
		}

		void CLogRegistry::unregisterFormatter(const std::string& name)
		{
			CMutex::ScopedLock lock(m_mutex);

			FormatterMap::iterator it = m_formatterMap.find(name);
			if (it != m_formatterMap.end())
				m_formatterMap.erase(it);
			else
				throw NotFoundException("logging formatter", name);
		}

		void CLogRegistry::clear()
		{
			CMutex::ScopedLock lock(m_mutex);

			m_channelMap.clear();
			m_formatterMap.clear();
		}

		static TSingletonHolder<CLogRegistry> sh;

		CLogRegistry& CLogRegistry::defaultRegistry()
		{
			return *sh.get();
		}

	}//end of namespace log
}//end of namespace JHCPP